﻿using Microsoft.Practices.Unity;
using Sasa.QualityTools.CodeAnalysis.Core.Models;
using Sasa.QualityTools.CodeAnalysis.Core.Utilities;
using Sasa.QualityTools.CodeAnalysis.Core.VisualStudio;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.ViewModels;
using System;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Commands.Behaviors.CodeAnalysis.Inspection
{
    public abstract class CreateCodeInspectorBehaviorBase : ICommandBehavior<CodeAnalysisCommandExecutionContext>
    {
        protected IUnityContainer Container { get; private set; }


        protected CreateCodeInspectorBehaviorBase(IUnityContainer container)
        {
            Container = container;
        }


        public abstract void Behave(CodeAnalysisCommandExecutionContext context);

        protected CodeInspectorViewModel BuildupCodeAnalysis(ISolution solution)
        {
            var model = new CodeInspectorViewModel();
            var config = CodeAnalysisConfiguration.Load(solution.ConfigurationPath);
            var option = Container.Resolve<IFxCopIntegratorPackage>().GeneralOption;

            model.CommandPath = option.FxCopCmdPath;
            model.CommandOption = FxCopCmdOptionBuilder.Build(solution);
            model.Coordinators.Add(new FxCopReportValueCoordinator { FxCopProjectPath = solution.FxCopProjectPath });
            model.Target = "FxCop Project File";
            model.Filter = new CodeAnalysisResultValueFileNameFilter(config.FilterPatterns);

            return model;
        }

        protected CodeInspectorViewModel BuildupCodeAnalysis(IProject project, params string[] typeNames)
        {
            var model = new CodeInspectorViewModel();
            model.Target = project.Name;

            if (!project.IsSupportedCodeAnalysis)
            {
                var reason = (!String.IsNullOrWhiteSpace(project.NotSupportedReason)) ? project.NotSupportedReason : "FxCop Integrator doesn't support to analyze this project.";
                model.SkipPeforming(reason);
                return model;
            }

            var config = CodeAnalysisConfiguration.Load(project.ConfigurationPath);
            config.Override(CodeAnalysisConfiguration.Load(project.Solution.ConfigurationPath));
            if (!config.EnableCodeAnalysis)
            {
                model.SkipPeforming("Code analysis is disabled.");
                return model;
            }

            // The report loader finds the path of tje FxCop report with the command line option.
            // So this behavior have to set model.CommandOption whether on-demand code analysis is skipped or not.
            var option = Container.Resolve<IFxCopIntegratorPackage>().GeneralOption;
            model.CommandPath = option.FxCopCmdPath;
            model.CommandOption = FxCopCmdOptionBuilder.Build(project, option.FxCopVersion, typeNames);
            foreach (var path in project.ReferenceAssemblyPaths)
            {
                model.ReferenceAssemblyPaths.Add(path);
            }
            model.Filter = new CodeAnalysisResultValueFileNameFilter(config.FilterPatterns);

            if (typeNames == null || typeNames.Length == 0)
            {
                var msbuild = MSBuildProject.Load(project.ProjectPath);
                if (msbuild.EnableCodeInspectionOnBuild)
                {
                    model.MarkAsCompletedOnBuildTime();
                    return model;
                }
            }

            return model;
        }
    }
}
